#include <QCoreApplication>
#include <QObject>
#include <QDebug>
#include <QDateTime>
#include <QDir>
#include <QTranslator>
#include <unistd.h>

#include "notification.h"

#define PROGRAM_NAME "kylin-activation-prompt"
#define LOG_NAME "/.log/kylin-activation/kylin-activation-prompt.log"

static FILE *fp_log = NULL;
QString toDir;

void msgHandler(QtMsgType type, const QMessageLogContext& context, const QString& msg)
{
    static char logPath[255] = {0};
    static int pid = 0;

    Q_UNUSED(context);

    QDateTime currentTime = QDateTime::currentDateTime();
    QString timeStr = currentTime.toString("yy.MM.dd hh:mm:ss +zzz");
    pid = (int)getpid();
    // 获取用于控制命令行输出的环境变量
    char *ctrlEnv = getenv("XXXX_DEBUG");
    QString env;

    // 格式化输出字符串，添加消息发生时间、消息等级
    QString outMsg;
    switch (type) {
    case QtDebugMsg:
        outMsg = QString("[%1 D .%2]: %3").arg(timeStr).arg(pid).arg(msg);
        break;
    case QtInfoMsg:
        outMsg = QString("[%1 D .%2]: %3").arg(timeStr).arg(pid).arg(msg);
        break;
    case QtWarningMsg:
        outMsg = QString("[%1 D .%2]: %3").arg(timeStr).arg(pid).arg(msg);
        break;
    case QtCriticalMsg:
        outMsg = QString("[%1 D .%2]: %3").arg(timeStr).arg(pid).arg(msg);
        break;
    case QtFatalMsg:
        outMsg = QString("[%1 D .%2]: %3").arg(timeStr).arg(pid).arg(msg);
    }

    if (fp_log != NULL) {
        // 日志文件存在，则输出到日志文件中
        fprintf(fp_log, "%s\n", outMsg.toUtf8().data());
        fflush(fp_log);
    }

    if (ctrlEnv != NULL) {
        // 环境变量为true或者1，则将信息输出到命令行
        env = QString(ctrlEnv).toLower();
        if ((env == "true") || (env == "1")) {
            fprintf(stdout, "%s\n", outMsg.toStdString().c_str());
            fflush(stdout);
        }
    }

    // 遇到致命错误，需要终止程序（这里终止程序是可选的）
    if (type == QtFatalMsg)
        abort();
}

void log_env_init(){
    static char logPath[98] = {0};
    bool _is_root = false;
    toDir = QDir::homePath();
    toDir += "/.log/kylin-activation/";
    QDir dir(toDir);
    if(!dir.exists()) {
        dir.mkdir(toDir);
    }

    std::string str = QDir::homePath().toStdString();
    const char* ch = str.c_str();
    sprintf(logPath, "%s%s", ch, LOG_NAME);

    if (access(logPath, F_OK|W_OK) == 0) { // log文件存在且可写
        if (fp_log == NULL)
            fp_log = fopen(logPath, "a+");
        QFileInfo info(logPath);
        if (info.size() > 1024*1024*200) { //10MB
            fclose(fp_log); fp_log = NULL;
            QFile fileclean(logPath);
            fileclean.open(QIODevice::WriteOnly | QIODevice::Text | QFile::Truncate);
            fileclean.close();
            if (fp_log == NULL)
                fp_log = fopen(logPath, "a+");
        }
    } else if (access(logPath, F_OK) != 0) { //文件不存在
        if (fp_log == NULL) {
            fp_log = fopen(logPath, "a+");
            if (fp_log == NULL)
                printf("Can't open logfile!\n");
        }
    } else {
        // log文件不可写，则需要判断是否被打开过，被打开过就需要关闭
        if (fp_log != NULL)
            fclose(fp_log);
        fp_log = NULL;
    }
}

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    QTranslator translator;
    QString locale = QLocale::system().name();
    translator.load(QString(":/kylin_activation_prompt_%1.qm").arg(locale));
    a.installTranslator(&translator);

    log_env_init();
    qInstallMessageHandler(msgHandler);

    notification *ntf = new notification();

    return a.exec();
}
